<template>
  <div>
    <!-- 面包屑导航区域 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>用户管理</el-breadcrumb-item>
      <el-breadcrumb-item>用户列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片视图区域 -->
    <el-card>
      <!-- 布局 -->
      <!-- gutter:col与col之间的间隙 -->
      <el-row :gutter="20">
        <!-- span:一行分24 -->
        <el-col :span="6">
          <!-- 搜索 -->
          <el-input placeholder="请输入内容" @clear="getUserList" v-model="query" clearable>
            <el-button slot="append" icon="el-icon-search" @click="getUserList"></el-button>
          </el-input>
        </el-col>
        <el-col :span="4">
          <el-button type="primary" @click="addUserDialogVisible = true">添加用户</el-button>
        </el-col>
      </el-row>
      <!-- 用户列表区域 -->
      <el-table :data="pageInfo.list" border stripe>
        <!-- 直接通过prop属性赋值，或者通过作用域插槽丰富多样化 -->
        <el-table-column label="#" type="index"></el-table-column>
        <el-table-column width="150" label="用户名" prop="username"></el-table-column>
        <el-table-column width="100" label="ID" prop="id"></el-table-column>
        <el-table-column width="100" label="密码" prop="password">
          <template slot-scope="scope">
            <el-tooltip effect="dark" content="重置密码" placement="top" :enterable="false">
              <el-button
                type="danger"
                @click="getInfoByID(scope.row.id)"
                size="mini"
                round
              >{{scope.row.password}}</el-button>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column width="200" label="邮箱" prop="email"></el-table-column>
        <el-table-column width="150" label="电话" prop="phone"></el-table-column>
        <el-table-column width="150" label="密保问题" prop="question"></el-table-column>
        <el-table-column width="150" label="密保答案" prop="answer">
          <template slot-scope="scope">
            <el-tooltip effect="dark" content="修改密保" placement="top" :enterable="false">
              <el-button type="text" @click="getInfoByID(scope.row.id)">{{scope.row.answer}}</el-button>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column width="119" label="权限">
          <template slot-scope="scope">
            <el-tag
              :type="scope.row.role === 1 ? 'danger' : 'success'"
            >{{scope.row.role === 1 ? '管理员' : '大会员'}}</el-tag>
          </template>
        </el-table-column>
        <el-table-column width="160" label="创建时间" prop="createTime"></el-table-column>
        <el-table-column width="160" label="最近更新" prop="updateTime"></el-table-column>
        <el-table-column width="150" label="操作">
          <template slot-scope="scope">
            <el-tooltip effect="dark" content="编 辑" placement="top-start" :enterable="false">
              <el-button
                type="primary"
                icon="el-icon-edit"
                @click="getInfoByID(scope.row.id)"
                size="small"
              ></el-button>
            </el-tooltip>
            <el-tooltip effect="dark" content="删 除" placement="top-end" :enterable="false">
              <el-button
                type="primary"
                icon="el-icon-delete"
                size="small"
                @click="delUserById(scope.row.id)"
              ></el-button>
            </el-tooltip>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="pageNum"
        :page-sizes="[1, 5, 10, 20]"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="pageInfo.total"
        :background="true"
      ></el-pagination>
    </el-card>
    <!-- 弹出添加用户的对话框  -->
    <el-dialog title="添加用户" :visible.sync="addUserDialogVisible" width="50%" center>
      <!-- content:内部主体在该span内 -->
      <span>
        <!-- addForm:用户表单数据   addFormRules:表单的验证规则;  ref：该form表单引用名称 -->
        <el-form
          :model="addForm"
          status-icon
          :rules="addFormRules"
          ref="addFormRef"
          label-width="100px"
        >
          <el-form-item label="用户名" prop="username">
            <!-- prop:验证规则属性 -->
            <el-input type="text" v-model="addForm.username" placeholder="请输入用户名"></el-input>
          </el-form-item>
          <el-form-item label="身份权限" prop="role">
            <el-radio-group v-model="addForm.role">
              <el-radio :label="1">
                <el-tag :type="'danger'">管理员</el-tag>
              </el-radio>
              <el-radio :label="0">
                <el-tag :type="'success'">大会员</el-tag>
              </el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="输入密码" prop="password">
            <!-- prop:验证规则属性 -->
            <el-input type="password" v-model="addForm.password" placeholder="请输入密码"></el-input>
          </el-form-item>
          <el-form-item label="确认密码" prop="checkpwd">
            <!-- prop:验证规则属性 -->
            <el-input type="password" v-model="addForm.checkpwd" placeholder="再次输入密码"></el-input>
          </el-form-item>
          <el-form-item label="联系方式" prop="phone">
            <!-- prop:验证规则属性 -->
            <el-input type="text" v-model="addForm.phone" placeholder="请输入联系方式"></el-input>
          </el-form-item>
          <el-form-item label="邮箱地址" prop="email">
            <!-- prop:验证规则属性 -->
            <el-input type="text" v-model="addForm.email" placeholder="请输入邮箱地址"></el-input>
          </el-form-item>
          <el-form-item label="密保问题" prop="question">
            <!-- prop:验证规则属性 -->
            <el-input type="text" v-model="addForm.question" placeholder="请输入密保问题"></el-input>
          </el-form-item>
          <el-form-item label="密保答案" prop="answer">
            <!-- prop:验证规则属性 -->
            <el-input type="password" v-model="addForm.answer" placeholder="请输入密保答案"></el-input>
          </el-form-item>
        </el-form>
      </span>
      <!-- 退出编辑的内嵌会话框 -->
      <el-dialog width="30%" title="是否退出编辑" :visible.sync="innerVisible" append-to-body center>
        <!-- footer: -->
        <span slot="footer" class="dialog-footer">
          <el-button type="primary" @click="innerVisibleClose">确 定</el-button>
        </span>
      </el-dialog>
      <!-- footer: -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="innerVisible = true">退出编辑</el-button>
        <el-button type="primary" @click="addUser">提 交</el-button>
      </span>
    </el-dialog>

    <!-- 弹出添加用户的对话框  -->
    <el-dialog
      title="编辑信息"
      :visible.sync="editUserDialogVisible"
      width="900px"
      @close="editUserDialogClose"
      center
    >
      <!-- 信息主体 -->
      <span>
        <el-row type="flex" justify="space-around">
          <el-col :span="10">
            <strong>登陆手机</strong>
            <hr />
            <br />
            <!-- model:表单数据来源   rules：表单规则   ref：表单引用对象 -->
            <el-form
              status-icon
              :model="editSubmit"
              :rules="editFormRules"
              ref="editFormPhoneRef"
              label-width="100px"
            >
              <el-form-item label="原手机号码">
                <small style="color:gray">{{editForm.phone}}</small>
              </el-form-item>
              <el-form-item label="新手机号码" prop="phone">
                <el-input type="password" v-model="editSubmit.phone"></el-input>
              </el-form-item>
              <el-form-item label="验证码">
                <el-input type="password" :disabled="true">
                  <el-button slot="append" :disabled="true">获取验证码</el-button>
                </el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" style="width:260px" @click="updatePhone">点击修改</el-button>
              </el-form-item>
            </el-form>
          </el-col>
          <el-col :span="10">
            <strong>绑定邮箱</strong>
            <hr />
            <br />
            <el-form
              status-icon
              :model="editSubmit"
              :rules="editFormRules"
              ref="editFormEmailRef"
              label-width="100px"
            >
              <el-form-item label="原邮箱">
                <small style="color:gray">{{editForm.email}}</small>
              </el-form-item>
              <el-form-item label="新邮箱" prop="email">
                <el-input type="password" v-model="editSubmit.email"></el-input>
              </el-form-item>
              <el-form-item label="验证码">
                <el-input type="password" :disabled="true">
                  <el-button slot="append" :disabled="true">获取验证码</el-button>
                </el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" style="width:260px" @click="updateEmail">点击修改</el-button>
              </el-form-item>
            </el-form>
          </el-col>
        </el-row>
        <el-row type="flex" justify="space-around">
          <el-col :span="10">
            <strong>修改密码</strong>
            <hr />
            <br />
            <el-form
              status-icon
              :model="editSubmit"
              :rules="editFormRules"
              ref="editFormPwdRef"
              label-width="100px"
            >
              <el-form-item label="原密码" prop="oldpwd">
                <el-input type="password" v-model="editSubmit.oldpwd"></el-input>
              </el-form-item>
              <el-form-item label="新密码" prop="password">
                <el-input type="password" v-model="editSubmit.password"></el-input>
              </el-form-item>
              <el-form-item label="确认密码" prop="checkpwd">
                <el-input type="password" v-model="editSubmit.checkpwd"></el-input>
              </el-form-item>
              <el-form-item>
                <el-button
                  type="primary"
                  style="width:260px"
                  @click="updatePasswordAnswer('password')"
                >点击修改</el-button>
              </el-form-item>
            </el-form>
          </el-col>
          <el-col :span="10">
            <strong>安全密保</strong>
            <hr />
            <br />
            <el-form
              status-icon
              :model="editSubmit"
              :rules="editFormRules"
              ref="editFormAnswerRef"
              label-width="100px"
            >
              <el-form-item label="密保问题">
                <small style="color:gray">{{editForm.question}}</small>
              </el-form-item>
              <el-form-item label="原密保答案" prop="oldanswer">
                <el-input type="password" v-model="editSubmit.oldanswer"></el-input>
              </el-form-item>
              <el-form-item label="新密保答案" prop="answer">
                <el-input type="password" v-model="editSubmit.answer"></el-input>
              </el-form-item>
              <el-form-item>
                <el-button
                  type="primary"
                  style="width:260px"
                  @click="updatePasswordAnswer('answer')"
                >点击修改</el-button>
              </el-form-item>
            </el-form>
          </el-col>
        </el-row>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 查询的关键字
      query: '',
      // 请求的页数
      pageNum: 1,
      // 请求的每页大小
      pageSize: 5,
      // 响应的信息
      pageInfo: '',
      // 添加用户的对话框状态
      addUserDialogVisible: false,
      // 内嵌框的状态
      innerVisible: false,
      // 表单的数据
      addForm: {
        username: '',
        role: 0,
        password: '',
        checkpwd: '',
        phone: 0,
        email: '',
        question: '',
        answer: ''
      },
      // 表单的验证规则对象
      addFormRules: {
        username: [
          // username的规则一
          {
            // 必填项？
            required: true,
            // 响应信息
            message: '请输入用户名',
            // 触发事件
            trigger: 'blur'
          },
          // username的规则二
          {
            // 最小长度
            min: 3,
            // 最大长度
            max: 9,
            // 信息
            message: '用户名的长度在3~9个字符之间',
            // 触发事件
            trigger: 'blur'
          },
          {
            validator: async (rule, value, callback) => {
              const { data: res } = await this.$axios.get('manage/user/check_valid', {
                params: {
                  str: value,
                  type: 'username'
                }
              })
              if (res.status !== 0) callback(new Error(res.msg))
              callback()
            },
            trigger: 'blur'
          }
        ],
        role: [
          {
            required: true
          }
        ],
        password: [
          {
            required: true,
            message: '请输入要设置的密码',
            trigger: 'blur'
          },
          {
            min: 6,
            max: 15,
            message: '密码长度在6~15个字符之间',
            trigger: 'blur'
          }
        ],
        checkpwd: [
          {
            validator: (rule, value, callback) => {
              if (value === '') callback(new Error('请再次输入密码'))
              if (value !== this.addForm.password) callback(new Error('上下输入密码不一致'))
              callback()
            },
            required: true,
            trigger: 'blur'
          }
        ],
        phone: [
          {
            validator: (rule, value, callback) => {
              if (value === '') callback(new Error('必填项'))
              const v = /^1[3456789]\d{9}$/
              if (!v.test(value)) callback(new Error('请输入有效的手机号码'))
              callback()
            },
            required: true,
            trigger: 'blur'
          }
        ],
        email: [
          {
            validator: async (rule, value, callback) => {
              if (value === '') callback(new Error('必填项'))
              const v = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
              if (!v.test(value)) callback(new Error('请输入有效的邮箱'))
              const { data: res } = await this.$axios.get('manage/user/check_valid', {
                params: {
                  str: value,
                  type: 'email'
                }
              })
              if (res.status !== 0) callback(new Error(res.msg))
              callback()
            },
            required: true,
            trigger: 'blur'
          }
        ],
        question: [
          {
            required: true,
            message: '必填项',
            trigger: 'blur'
          },
          {
            min: 3,
            max: 20,
            message: '密保问题长度在3~20个字符之间',
            trigger: 'blur'
          }
        ],
        answer: [
          {
            validator: (rule, value, callback) => {
              if (value === '') callback(new Error('密保答案不能为空'))
              if (value === this.addForm.question) callback(new Error('密保答案不能与密保问题一致'))
              callback()
            },
            required: true,
            trigger: 'blur'
          }
        ]
      },
      // 编辑信息的主体
      editUserDialogVisible: false,
      // 获取单个用户的数据
      editForm: {},
      // 修改用户信息的规则
      editFormRules: {
        phone: [
          {
            validator: (rule, value, callback) => {
              if (value === this.editForm.phone) callback(new Error('与原手机号一致'))
              const v = /^1[3456789]\d{9}$/
              if (!v.test(value)) callback(new Error('请输入有效的手机号码'))
              if (value === '') callback(new Error(''))
              callback()
            },
            trigger: 'blur'
          }
        ],
        email: [
          {
            validator: async (rule, value, callback) => {
              if (value === this.editForm.email) callback(new Error('与原邮箱一致'))
              const v = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
              if (!v.test(value)) callback(new Error('请输入有效的邮箱'))
              if (value === '') callback(new Error(''))
              const { data: res } = await this.$axios.get('manage/user/check_valid', {
                params: {
                  str: value,
                  type: 'email'
                }
              })
              if (res.status !== 0) callback(new Error(res.msg))
              callback()
            },
            trigger: 'blur'
          }
        ],
        oldpwd: [
          {
            validator: (rule, value, callback) => {
              if (value === '') callback(new Error(''))
              const match = /^.{6,15}$/
              if (!match.test(value)) callback(new Error('密码长度在6~15个字符之间'))
              callback()
            },
            trigger: 'blur'
          }
        ],
        password: [
          {
            validator: (rule, value, callback) => {
              if (value === '') callback(new Error(''))
              const match = /^.{6,15}$/
              if (!match.test(value)) callback(new Error('密码长度在6~15个字符之间'))
              if (value === this.editSubmit.oldpwd) callback(new Error('新密码与原密码一致'))
              callback()
            },
            trigger: 'blur'
          }
        ],
        checkpwd: [
          {
            validator: (rule, value, callback) => {
              if (value === '') callback(new Error(''))
              if (value !== this.editSubmit.password) callback(new Error('上下输入密码不一致'))
              callback()
            },
            trigger: 'blur'
          }
        ],
        oldanswer: [
          {
            validator: (rule, value, callback) => {
              if (value === '') callback(new Error(''))
              if (value === this.editForm.question) callback(new Error('密保答案不能与密保问题一致'))
              callback()
            },
            trigger: 'blur'
          }
        ],
        answer: [
          {
            validator: (rule, value, callback) => {
              if (value === '') callback(new Error(''))
              if (value === this.editSubmit.oldanswer) callback(new Error('新密保答案与原密保答案一致'))
              if (value === this.editForm.question) callback(new Error('密保答案不能与密保问题一致'))
              callback()
            },
            trigger: 'blur'
          }
        ]
      },
      // 修改密码
      editSubmit: {
        id: '',
        username: '',
        password: '',
        email: '',
        phone: '',
        question: '',
        answer: '',
        checkpwd: '',
        oldpwd: '',
        oldanswer: ''
      },
      // 删除对话框
      delUserDialogVisible: false,
      // 删除的ID
      deleteId: null
    }
  },
  created() {
    this.getUserList()
  },
  methods: {
    async getUserList() {
      // get 请求，('url',{params:参数})
      const { data: res } = await this.$axios.get('manage/user/get_user_list', {
        params: {
          query: this.query,
          pageNum: this.pageNum,
          pageSize: this.pageSize
        }
      })
      // 如果返回的数据状态码不等于0，说明是错误信息，弹框提示错误信息
      if (res.status !== 0) return this.$message.error(res.msg)
      // 否则，将数据传给对象
      this.pageInfo = res.data
    },
    // @size-change 监听 和 处理 页码大小变动时触发的事件
    handleSizeChange(newSize) {
      // 将新的每页大小赋值给data中的全局变量，然后向后台请求数据，更新页面
      this.pageSize = newSize
      this.getUserList()
    },
    // @current-change 监听 和 处理 当前页变动时触发的事件
    handleCurrentChange(newPage) {
      // 将新的页数赋值给data中的全局变量，然后向后台请求数据，更新页面
      this.pageNum = newPage
      this.getUserList()
    },
    // 是否退出编辑 内嵌框
    innerVisibleClose() {
      // 内嵌框 关闭
      this.innerVisible = false
      // 会话框 关闭
      this.addUserDialogVisible = false
      // 清楚会话框数据
      this.$refs.addFormRef.resetFields()
    },
    // 添加新用户
    addUser() {
      // 提交前预检
      this.$refs.addFormRef.validate(async valid => {
        // 如果valid预检false，直接返回
        if (!valid) return
        // 发送添加数据的请求
        const { data: res } = await this.$axios.post('manage/user/register', this.addForm)
        // 添加失败
        if (res.status !== 0) return this.$message.error(res.msg)
        // 添加成功
        this.$message.success(res.msg)
        // 关闭对话框
        this.addUserDialogVisible = false
        // 刷新数据列表
        this.getUserList()
      })
    },
    // 通过id获取用户信息
    async getInfoByID(id) {
      this.editUserDialogVisible = true
      const { data: res } = await this.$axios.get('manage/user/get_info', {
        params: {
          id: id
        }
      })
      if (res.status !== 0) return this.$message.error(res.msg)
      // 数据成功获取后存储起来
      this.editForm = res.data
    },
    // 更改登陆手机
    updatePhone() {
      this.$refs.editFormPhoneRef.validate(async valid => {
        if (!valid) return
        const req = new URLSearchParams()
        req.append('id', this.editForm.id)
        req.append('str', this.editSubmit.phone)
        req.append('type', 'phone')
        const { data: res } = await this.$axios.post('manage/user/update_phone_email', req)
        if (res.status !== 0) return this.$message.error(res.msg)
        this.$message.success(res.msg)
        this.$refs.editFormPhoneRef.resetFields()
        this.editForm = res.data
      })
    },
    // 更改邮箱
    updateEmail() {
      this.$refs.editFormEmailRef.validate(async valid => {
        if (!valid) return
        const req = new URLSearchParams()
        req.append('id', this.editForm.id)
        req.append('str', this.editSubmit.email)
        req.append('type', 'email')
        const { data: res } = await this.$axios.post('manage/user/update_phone_email', req)
        if (res.status !== 0) return this.$message.error(res.msg)
        this.$message.success(res.msg)
        this.$refs.editFormEmailRef.resetFields()
        this.editForm = res.data
      })
    },
    // 更改密码/密保答案
    updatePasswordAnswer(type) {
      this.$refs.editFormPwdRef.validate(async valid => {
        if (!valid) return
        // const req = new URLSearchParams() //后台只能通过@RequestBody 获取JSON数据，或者根据参数名称直接获取
        // req.append('newstr', this.editSubmit.password)
        // req.append('oldstr', this.editSubmit.oldpwd)
        // req.append('type', 'password')
        const req = new FormData() // 后台可以通过@ResquestParam 注解获取对应参数名称的数据
        if (type === 'password') {
          req.append('newstr', this.editSubmit.password)
          req.append('oldstr', this.editSubmit.oldpwd)
          req.append('type', 'password')
        } else if (type === 'answer') {
          req.append('newstr', this.editSubmit.answer)
          req.append('oldstr', this.editSubmit.oldanswer)
          req.append('type', 'answer')
        } else return this.$message.error('参数错误！')
        const { data: res } = await this.$axios.put('manage/user/update_password_answer/' + this.editForm.id, req)
        if (res.status !== 0) return this.$message.error(res.msg)
        this.$message.success(res.msg)
        this.$refs.editFormPwdRef.resetFields()
        this.editForm = res.data
      })
    },
    // 会话框关闭时重置表单信息
    editUserDialogClose() {
      this.editForm = {}
      this.editSubmit = {
        id: '',
        username: '',
        password: '',
        email: '',
        phone: '',
        question: '',
        answer: '',
        checkpwd: '',
        oldpwd: '',
        oldanswer: ''
      }
      this.getUserList()
    },
    // 删除用户
    delUserById(id) {
      // 询问是否删除，确认执行then返回confirm，取消执行catch返回cancel
      this.$confirm('此操作将永久删除该用户，是否继续？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async () => {
          this.$message.success('执行操作！')
          const { data: res } = await this.$axios.delete('manage/user/delete_id/' + id)
          if (res.status !== 0) return this.$message.error(res.msg)
          this.$message.success(res.msg)
          this.deleteId = null
          this.delUserDialogVisible = false
          this.getUserList()
        })
        .catch(() => this.$message.info('取消操作！'))
    }
  }
}
</script>

<style lang="less" scoped>
</style>
